use axum::extract::Query;
use axum::middleware;
use axum::response::{IntoResponse, Response};
use axum::{response::Html, Router};
use model::ModelController;
use serde::Deserialize;
use tower_cookies::{CookieManagerLayer};

#[allow(unused)]
pub use self::error::{Error, Result};

mod error;
mod model;
mod web;

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize ModelController
    let mc = ModelController::new().await?;

    let routes_apis = web::routes_tickets::routes(mc.clone())
        .route_layer(middleware::from_fn(web::mw_auth::mv_require_auth));
    let routes_all = Router::new()
        // .route("/hello", get(handler_hello), )
        // .route("/helloparam", get(handler_params))
        .merge(web::routes_login::routes())
        .nest("/api", web::routes_tickets::routes(mc.clone()))
        .layer(middleware::map_response(main_response_mapper))
        .layer(CookieManagerLayer::new());

    // start server
    //
    let listener = tokio::net::TcpListener::bind("0.0.0.0:5852").await.unwrap();
    axum::serve(listener, routes_all).await.unwrap();
    Ok(())
}

async fn main_response_mapper(res: Response) -> Response {
    println!("_>> {:<12} - main_response_mapper", "RESP_MAPPER");

    println!();
    res
}

// 简单的Handler，传回HTML
async fn handler_hello() -> impl IntoResponse {
    println!("--> {:<12} - handler_hello", "HANDLER");
    Html("Hello <strong>axum</strong>!")
}

// 处理Params
#[derive(Debug, Deserialize)]
struct HelloParams {
    name: Option<String>,
}

async fn handler_params(Query(params): Query<HelloParams>) -> impl IntoResponse {
    println!("--> {:<12} - handler_params - {params:?}", "HANDLER");

    let name = params.name.as_deref().unwrap_or("World");
    Html(format!("Hello <strong>{name}</strong>!"))
}
